package com.wanli.agent.utils;

import android.util.Log;

import com.wanli.agent.BuildConfig;

import org.json.JSONObject;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Locale;

/**
 * @desc：日志输出类
 */
public class LogUtils {
    private static final String LOG_PREFIX = "WanliAgent";
    private static final int LOG_PREFIX_LENGTH = LOG_PREFIX.length();
    private static final int MAX_LOG_TAG_LENGTH = 23;
    private static final String TAG = "WanliAgent";

    public static final boolean DEBUG = BuildConfig.DEBUG;

    public static String makeLogTag(String str) {
        if (str.length() > MAX_LOG_TAG_LENGTH - LOG_PREFIX_LENGTH) {
            return LOG_PREFIX + str.substring(0, MAX_LOG_TAG_LENGTH - LOG_PREFIX_LENGTH - 1);
        }

        return LOG_PREFIX + str;
    }

    private static StackTraceElement getCallerStackTraceElement() {
        return Thread.currentThread().getStackTrace()[4];
    }

    private static String makeLogTag(StackTraceElement caller) {
        if (caller == null) {
            return makeLogTag("service");
        }
        String className = caller.getClassName();
        className = className.substring(className.lastIndexOf(".") + 1);
        return String.format(Locale.CHINA, "%s.%s(L:%d)",
                className,
                caller.getMethodName(),
                caller.getLineNumber());
    }

    /**
     * debug信息
     *
     * @param msg
     */
    public static void debug(String msg) {
        if (DEBUG) {
            String tag = makeLogTag(getCallerStackTraceElement());
            Log.v(TAG, msg);
        }
    }

    /**
     * debug信息
     *
     * @param msg
     */
    public static void d(String msg) {
        if (DEBUG) {
            String tag = makeLogTag(getCallerStackTraceElement());
            Log.v(TAG, msg);
        }
    }

    /**
     * debug信息
     *
     * @param msg
     */
    public static void d(String TAG, String msg) {
        if (DEBUG) {
        String tag = makeLogTag(getCallerStackTraceElement());
        Log.v(TAG, msg);
        }
    }

    /**
     * warning信息
     *
     * @param msg
     */
    public static void w(String msg) {
        if (DEBUG) {
            String tag = makeLogTag(getCallerStackTraceElement());
            Log.w(TAG, msg);
        }
    }

    /**
     * warning信息
     *
     * @param msg
     */
    public static void w(String TAG, String msg) {
        if (DEBUG) {
            String tag = makeLogTag(getCallerStackTraceElement());
            Log.w(TAG, msg);
        }
    }

    /**
     * error信息
     *
     * @param msg
     */
    public static void e(String msg) {
        if (DEBUG) {
            String tag = makeLogTag(getCallerStackTraceElement());
            Log.e(TAG, msg);
        }
    }

    /**
     * error信息
     *
     * @param msg
     */
    public static void e(String TAG, String msg) {
        if (DEBUG) {
        String tag = makeLogTag(getCallerStackTraceElement());
        Log.e(TAG, msg);
        }
    }

    public static String toString(Object object) {
        try {
            JSONObject jsonObject = new JSONObject();
            StringBuilder buffer = new StringBuilder();
            Class<?> cls = object.getClass();
            buffer.append(cls.getSimpleName()).append(":");
            while (cls != null && cls != Object.class) {
                LogUtils.getField(object, cls, jsonObject);
                cls = cls.getSuperclass();
            }
            buffer.append(jsonObject.toString());
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private static void getField(Object object, Class<?> cls, JSONObject jsonObject) {
        try {
            Field[] fields = cls.getDeclaredFields();
            for (Field field : fields) {
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod) || Modifier.isTransient(mod)) {
                    continue;
                }
                field.setAccessible(true);
                jsonObject.put(field.getName(), field.get(object));
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
    private static StringBuffer sb = new StringBuffer();
    private static OutputStream outputStream= new OutputStream() {
        @Override
        public void write(int b) throws IOException {

        }
    };

    public static PrintStream printStream = new PrintStream(outputStream){
        @Override
        public void println(String x) {
            w(sb.append(x).toString());
            sb.delete(0, sb.length());
        }

        @Override
        public void print(String s) {
            sb.append(s);
        }
    };
}